
    
<template>
  <!-- 无限滚动列表容器 -->
  <view class="infinite-list">
    <!-- 遍历列表数据，渲染每一项 -->
    <view v-for="(item, index) in list" :key="index">
      <!-- 插槽：允许父组件自定义每一项的渲染内容 -->
      <slot :item="item" :index="index"></slot>
    </view>
    <!-- 加载更多组件，根据状态显示不同内容 -->
    <wd-loadmore :state="state" @reload="loadmore" />
  </view>
</template>
      
  <script setup lang="ts">
import { onLoad, onReachBottom } from '@dcloudio/uni-app'

// 定义组件的 Props
const props = defineProps({
  /**
   * 当前页码
   * @type {number}
   * @default 0
   */
  pageNo: {
    type: Number,
    default: 0,
  },
  /**
   * 每页数据条数
   * @type {number}
   * @default 15
   */
  limit: {
    type: Number,
    default: 15,
  },
})

// 定义组件的事件
const emit = defineEmits(['loadData'])

// 定义响应式数据
const state = ref<string>('loading') // 加载状态：loading | finished | error
const list = ref<number[]>([]) // 列表数据
const pageNo = ref<number>(props.pageNo) // 当前页码
const limit = ref<number>(props.limit) // 每页数据条数
const total = ref<number>(0) // 数据总条数

// 监听页面滚动到底部事件
onReachBottom(() => {
  if (state.value !== 'finished' && state.value !== 'error') {
    loadmore()
  }
})

// 页面加载时触发数据加载
onLoad(() => {
  loadmore()
})

/**
 * loadData 加载表格数据方法
 * 加载数据后，需要根据查询结果设置下面内容
 * 1. 设置总条数
 * 2. 设置当前页数据
 * 3. 设置状态
 *
 * 示例：
 * const infiniteListRef = ref<InstanceType<typeof InfiniteList>>()
 * const newList = [获取的当前页数据]
 * infiniteListRef.value.setTotal(总条数)
 * infiniteListRef.value.setList(newList)
 * if (infiniteListRef.value.getList().length >= 总条数) {
 *   infiniteListRef.value.setState('finished') // 没有更多数据
 * } else {
 *   infiniteListRef.value.setState('loading') // 还有更多数据
 * }
 */
function loadmore() {
  pageNo.value += 1
  emit('loadData', pageNo.value, limit.value)
}

/**
 * 设置数据总条数
 * @param {number} newTotal - 数据总条数
 */
function setTotal(newTotal: number) {
  total.value = newTotal
}

/**
 * 设置当前页数据
 * @param {number[]} newList - 当前页数据
 */
function setList(newList: number[]) {
  list.value = list.value.concat(newList)
}

/**
 * 设置加载状态
 * @param {string} newState - 加载状态：loading | finished | error
 */
function setState(newState: string) {
  state.value = newState
}

function clearList() {
  list.value = []
  pageNo.value = 0
  total.value = 0
  state.value = 'loading'
}

// 暴露组件方法给父组件
defineExpose({
  setTotal,
  setList,
  clearList,
  setState,
  getList: () => list.value,
  getState: () => state.value,
})
</script>
<style scoped lang="scss">
/* 无限滚动列表样式 */
.infinite-list {
  width: 100%;
  height: 100%;
}
</style>
      